namespace Microsoft.VisualStudio.EnterpriseTools.OperationDesigner
{
    using Microsoft.VisualStudio.EnterpriseTools.ArtifactModel.Clr;
    using Microsoft.VisualStudio.EnterpriseTools.Shell;
    using Microsoft.VisualStudio.Modeling;
    using Microsoft.VisualStudio.Modeling.ArtifactMapper;
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Globalization;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Windows.Forms.Design;

    public class SummaryForm : DialogBase
    {
        private const int buttonWidthClearance = 8;
        private Button cancelButton;
        private ClrElement clrElement;
        private Container components;
        private string f1Keyword;
        private static Size lastSize = Size.Empty;
        private Button okButton;
        private TableLayoutPanel okCancelTableLayoutPanel;
        private Panel textBoxContainer;
        private bool textChanged;
        private const string webMethodAttributeName = "System.Web.Services.WebMethod";
        private const string webMethodAttributeName2 = "WebMethod";
        private const string webMethodDescriptionArgument = "Description";

        public SummaryForm(IServiceProvider serviceProvider, ClrElement element, string f1Keyword) : base(serviceProvider)
        {
            this.InitializeComponent();
            base.FormBorderStyle = FormBorderStyle.Sizable;
            this.f1Keyword = f1Keyword;
            IUIService service = (base.ServiceProvider != null) ? (base.ServiceProvider.GetService(typeof(IUIService)) as IUIService) : null;
            if (service != null)
            {
                Font font = service.Styles["DialogFont"] as Font;
                if (font != null)
                {
                    this.Font = font;
                }
            }
            this.textBoxContainer.Text = "textBoxContainer";
            this.okCancelTableLayoutPanel.Text = "okCancelTableLayoutPanel";
            if (lastSize != Size.Empty)
            {
                base.Size = lastSize;
            }
            this.clrElement = element;
            this.textChanged = false;
            ArrayList commentFields = new ArrayList(5);
            Language language = element.Language;
            if (language.CanReverseEngineerComments(element, ClrElement.DocSummaryMetaAttributeGuid))
            {
                commentFields.Add(new CommentField(ClrBranchStrings.GetString("SummaryCommentTitle"), 2, this.clrElement.Store.MetaDataDirectory.FindMetaAttribute(ClrElement.DocSummaryMetaAttributeGuid), language.CanForwardEngineerComments(element, ClrElement.DocSummaryMetaAttributeGuid)));
            }
            if (language.CanReverseEngineerComments(element, ClrMethod.DocReturnsMetaAttributeGuid))
            {
                commentFields.Add(new CommentField(ClrBranchStrings.GetString("ReturnsCommentTitle"), 2, this.clrElement.Store.MetaDataDirectory.FindMetaAttribute(ClrMethod.DocReturnsMetaAttributeGuid), language.CanForwardEngineerComments(element, ClrMethod.DocReturnsMetaAttributeGuid)));
            }
            if (language.CanReverseEngineerComments(element, ClrDelegate.DocReturnsMetaAttributeGuid))
            {
                commentFields.Add(new CommentField(ClrBranchStrings.GetString("ReturnsCommentTitle"), 2, this.clrElement.Store.MetaDataDirectory.FindMetaAttribute(ClrDelegate.DocReturnsMetaAttributeGuid), language.CanForwardEngineerComments(element, ClrDelegate.DocReturnsMetaAttributeGuid)));
            }
            ClrMethod method = element as ClrMethod;
            if (method != null)
            {
                ClrAttributeInstance instance = this.FindWebMethodAttribute(method);
                if (instance != null)
                {
                    commentFields.Add(new CommentField(ClrBranchStrings.GetString("WSDLCommentTitle"), 4, instance.Name, true));
                }
            }
            if (language.CanReverseEngineerComments(element, ClrProperty.DocValueMetaAttributeGuid))
            {
                commentFields.Add(new CommentField(ClrBranchStrings.GetString("ValueCommentTitle"), 2, this.clrElement.Store.MetaDataDirectory.FindMetaAttribute(ClrProperty.DocValueMetaAttributeGuid), language.CanForwardEngineerComments(element, ClrProperty.DocValueMetaAttributeGuid)));
            }
            if (language.CanReverseEngineerComments(element, ClrElement.DocRemarksMetaAttributeGuid))
            {
                commentFields.Add(new CommentField(ClrBranchStrings.GetString("RemarksCommentTitle"), 6, this.clrElement.Store.MetaDataDirectory.FindMetaAttribute(ClrElement.DocRemarksMetaAttributeGuid), language.CanForwardEngineerComments(element, ClrElement.DocRemarksMetaAttributeGuid)));
            }
            this.AddCommentFields(commentFields);
        }

        private void AddCommentField(CommentField field, DockStyle textBoxDockStyle, int tabIndex)
        {
            Label label = new Label();
            label.FlatStyle = FlatStyle.System;
            label.Text = field.Name;
            label.Dock = DockStyle.Top;
            label.Enabled = field.Enabled;
            label.TabIndex = tabIndex;
            label.Height = this.Font.Height + 4;
            TextBox box = new TextBox();
            box.Multiline = true;
            box.Dock = textBoxDockStyle;
            box.Height = (this.Font.Height * field.Lines) + 10;
            box.TextChanged += new EventHandler(this.OnSummaryTextChanged);
            box.ScrollBars = ScrollBars.Vertical;
            box.Enabled = field.Enabled;
            box.TabIndex = tabIndex + 1;
            box.Tag = field.Tag;
            if (field.Enabled)
            {
                MetaAttributeInfo attribute = field.Tag as MetaAttributeInfo;
                if (attribute != null)
                {
                    box.Text = SummaryHelper.StripValue(this.clrElement.GetAttributeValue(attribute).ToString(), true);
                }
                else if (this.IsWebMethodAttributeName(field.Tag))
                {
                    ClrAttributeInstance instance = this.FindWebMethodAttribute((ClrMethod) this.clrElement);
                    if (instance != null)
                    {
                        string namedArgument = instance.GetNamedArgument("Description");
                        if (!string.IsNullOrEmpty(namedArgument))
                        {
                            box.Text = SummaryHelper.WSDLDescriptionToText(namedArgument.Trim(new char[] { '"' }));
                            box.WordWrap = true;
                        }
                    }
                }
            }
            if (textBoxDockStyle == DockStyle.Top)
            {
                Splitter splitter = new Splitter();
                splitter.Dock = DockStyle.Top;
                splitter.Height = 4;
                this.textBoxContainer.Controls.Add(splitter);
            }
            this.textBoxContainer.Controls.Add(box);
            this.textBoxContainer.Controls.Add(label);
        }

        private void AddCommentFields(ArrayList commentFields)
        {
            try
            {
                this.textBoxContainer.SuspendLayout();
                this.AddCommentField((CommentField) commentFields[commentFields.Count - 1], DockStyle.Fill, (commentFields.Count - 1) * 2);
                for (int i = commentFields.Count - 2; i >= 0; i--)
                {
                    this.AddCommentField((CommentField) commentFields[i], DockStyle.Top, i * 2);
                }
                this.okButton.TabIndex += commentFields.Count * 2;
                this.cancelButton.TabIndex += commentFields.Count * 2;
            }
            finally
            {
                this.textBoxContainer.ResumeLayout();
            }
        }

        private CommitDialogResult CommitCommentChanges()
        {
            CommitDialogResult commitOK = CommitDialogResult.CommitOK;
            if (this.textChanged)
            {
                try
                {
                    using (Transaction transaction = this.clrElement.Store.TransactionManager.BeginTransaction(ClrBranchStrings.GetString("ChangeSummaryUndoText")))
                    {
                        foreach (Control control in this.textBoxContainer.Controls)
                        {
                            if (!control.Enabled)
                            {
                                continue;
                            }
                            MetaAttributeInfo attribute = control.Tag as MetaAttributeInfo;
                            if (attribute != null)
                            {
                                string currentValue = (string) this.clrElement.GetAttributeValue(attribute);
                                string xmlComment = SummaryHelper.RestoreValue(currentValue, control.Text, true);
                                if (!TypeModelUtility.IsWellFormedXMLString(xmlComment))
                                {
                                    DialogResult oK = DialogResult.OK;
                                    if (base.ServiceProvider != null)
                                    {
                                        string messageText = TypeSystemResources.GetString("NotWellFormedXMLComment", CultureInfo.CurrentUICulture);
                                        oK = PackageUtility.ShowMessageBox(base.ServiceProvider, messageText, 1, 0, 3);
                                    }
                                    commitOK = (oK == DialogResult.OK) ? CommitDialogResult.KeepDialogBoxUp : CommitDialogResult.CancelDialog;
                                    lastSize = base.Size;
                                    control.Focus();
                                    return commitOK;
                                }
                                this.clrElement.SetAttributeValue(attribute, xmlComment);
                                continue;
                            }
                            if (this.IsWebMethodAttributeName(control.Tag) && (this.FindWebMethodAttribute((ClrMethod) this.clrElement) != null))
                            {
                                this.clrElement.SetNamedAttributeArgument("System.Web.Services.WebMethod", "WebMethod", "Description", SummaryHelper.TextToWSDLDescription(control.Text), TreatAttributeArgumentValueAs.StringValue);
                            }
                        }
                        transaction.Commit();
                    }
                }
                catch (ArtifactHandlerException exception)
                {
                    if (base.ServiceProvider != null)
                    {
                        IUIService service = base.ServiceProvider.GetService(typeof(IUIService)) as IUIService;
                        if (service != null)
                        {
                            service.ShowError(exception.Message);
                        }
                    }
                    commitOK = CommitDialogResult.KeepDialogBoxUp;
                    int count = this.textBoxContainer.Controls.Count;
                    if (count > 0)
                    {
                        for (int i = count - 1; i >= 0; i--)
                        {
                            Control control2 = this.textBoxContainer.Controls[i];
                            if ((control2.Enabled && (control2 is TextBox)) && (control2.Text.Length != 0))
                            {
                                control2.Focus();
                                goto Label_0225;
                            }
                        }
                    }
                }
            }
        Label_0225:
            lastSize = base.Size;
            return commitOK;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private ClrAttributeInstance FindWebMethodAttribute(ClrMethod method)
        {
            IList clrAttributeInstance = method.GetClrAttributeInstance("System.Web.Services.WebMethod");
            if (clrAttributeInstance.Count == 0)
            {
                clrAttributeInstance = method.GetClrAttributeInstance("WebMethod");
            }
            if (clrAttributeInstance.Count != 0)
            {
                return (ClrAttributeInstance) clrAttributeInstance[0];
            }
            return null;
        }

        private void InitializeComponent()
        {
            ComponentResourceManager manager = new ComponentResourceManager(typeof(SummaryForm));
            this.okButton = new Button();
            this.cancelButton = new Button();
            this.textBoxContainer = new Panel();
            this.okCancelTableLayoutPanel = new TableLayoutPanel();
            this.okCancelTableLayoutPanel.SuspendLayout();
            base.SuspendLayout();
            manager.ApplyResources(this.okButton, "okButton");
            this.okButton.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            this.okButton.Margin = new Padding(0, 0, 3, 0);
            this.okButton.MinimumSize = new Size(0x4b, 0x17);
            this.okButton.Name = "okButton";
            this.okButton.Padding = new Padding(10, 0, 10, 0);
            this.okButton.Click += new EventHandler(this.OnOKButtonClick);
            manager.ApplyResources(this.cancelButton, "cancelButton");
            this.cancelButton.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            this.cancelButton.DialogResult = DialogResult.Cancel;
            this.cancelButton.Margin = new Padding(3, 0, 0, 0);
            this.cancelButton.MinimumSize = new Size(0x4b, 0x17);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Padding = new Padding(10, 0, 10, 0);
            manager.ApplyResources(this.textBoxContainer, "textBoxContainer");
            this.textBoxContainer.Name = "textBoxContainer";
            manager.ApplyResources(this.okCancelTableLayoutPanel, "okCancelTableLayoutPanel");
            this.okCancelTableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            this.okCancelTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f));
            this.okCancelTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f));
            this.okCancelTableLayoutPanel.Controls.Add(this.okButton, 0, 0);
            this.okCancelTableLayoutPanel.Controls.Add(this.cancelButton, 1, 0);
            this.okCancelTableLayoutPanel.Margin = new Padding(3, 6, 3, 3);
            this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel";
            this.okCancelTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50f));
            this.okCancelTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50f));
            base.AccessibleRole = AccessibleRole.Dialog;
            manager.ApplyResources(this, "$this");
            base.AutoScaleMode = AutoScaleMode.Font;
            base.CancelButton = this.cancelButton;
            base.Controls.Add(this.okCancelTableLayoutPanel);
            base.Controls.Add(this.textBoxContainer);
            base.HelpButton = true;
            base.MaximizeBox = false;
            base.MinimizeBox = false;
            base.Name = "SummaryForm";
            base.ShowIcon = false;
            base.ShowInTaskbar = false;
            this.okCancelTableLayoutPanel.ResumeLayout(false);
            this.okCancelTableLayoutPanel.PerformLayout();
            base.ResumeLayout(false);
            base.PerformLayout();
        }

        private bool IsWebMethodAttributeName(object name)
        {
            if (!"System.Web.Services.WebMethod".Equals(name))
            {
                return "WebMethod".Equals(name);
            }
            return true;
        }

        protected override void OnLayout(LayoutEventArgs e)
        {
            base.OnLayout(e);
            Point location = this.okButton.Location;
            Size size = this.okButton.Size;
            Point point2 = this.cancelButton.Location;
            int num = location.X + size.Width;
            if ((point2.X < num) || ((point2.X - num) < 8))
            {
                int x = (point2.X - 8) - size.Width;
                if (x < 0)
                {
                    x = 0;
                }
                this.okButton.Location = new Point(x, location.Y);
            }
        }

        private void OnOKButtonClick(object sender, EventArgs e)
        {
            switch (this.CommitCommentChanges())
            {
                case CommitDialogResult.CommitOK:
                    base.DialogResult = DialogResult.OK;
                    return;

                case CommitDialogResult.CancelDialog:
                    base.DialogResult = DialogResult.Cancel;
                    break;

                case CommitDialogResult.KeepDialogBoxUp:
                    break;

                default:
                    return;
            }
        }

        private void OnSummaryTextChanged(object sender, EventArgs e)
        {
            this.textChanged = true;
        }

        protected override string F1Keyword
        {
            get
            {
                if (this.f1Keyword == null)
                {
                    return "VS.ClrBranches.SummaryForm";
                }
                return this.f1Keyword;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct CommentField
        {
            public string Name;
            public object Tag;
            public int Lines;
            public bool Enabled;
            public CommentField(string name, int lines, object tag, bool enabled)
            {
                this.Name = name;
                this.Tag = tag;
                this.Lines = lines;
                this.Enabled = enabled;
            }
        }

        private enum CommitDialogResult
        {
            CommitOK,
            CancelDialog,
            KeepDialogBoxUp
        }
    }
}

